import sll.*;
import sllvm.Interpreter;

public class Main
{
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// 2 print args
		Stm progLivro =
			new CompoundStm(new AssignStm("a",
			new OpExp(new NumExp(5),
			OpExp.Plus, new NumExp(3))),
			new CompoundStm(new AssignStm("b",
			new EseqExp(new PrintStm(new PairExpList(new IdExp("a"),
			new LastExpList(new OpExp(new IdExp("a"),
			OpExp.Minus,new NumExp(1))))),
			new OpExp(new NumExp(10), OpExp.Times,
			new IdExp("a")))),
			new PrintStm(new LastExpList(new IdExp("b")))));
	
		// a := 5; b := 3; print ( a, b, ( print( b ), a ) )
		Stm prog0 = new CompoundStm(
			new AssignStm("a", new NumExp(5)), // a := 5;
			
			new CompoundStm(
				new AssignStm("b", new NumExp(3)), // a := 5; b := 3;
				
				new PrintStm(new PairExpList(
					new IdExp("a"),				// a := 5; b := 3; print ( a, 
					
					new PairExpList(
						new IdExp("b"),  	// a := 5; b := 3; print ( a, b,
						
						new LastExpList(new EseqExp(	
							new PrintStm(				
									new LastExpList(new IdExp("b"))	// a := 5; b := 3; print ( a, b, ( print( b ), 
								),
							
							new IdExp("a")	// a := 5; b := 3; print ( a, b, ( print( b ), a ) )
						))
					)
				))
			)				
		);
		
		// a := 5; b := 3; print ( a, b, ( print( b , 0, 1, 2 ), a ) )
		Stm prog1 = new CompoundStm(
			new AssignStm("a", new NumExp(5)), // a := 5;
			
			new CompoundStm(
				new AssignStm("b", new NumExp(3)), // a := 5; b := 3;
				
				new PrintStm(new PairExpList(
					new IdExp("a"),				// a := 5; b := 3; print ( a, 
					
					new PairExpList(
						new IdExp("b"),  	// a := 5; b := 3; print ( a, b,
						
						new LastExpList(new EseqExp(	
							new PrintStm(				
								
									new PairExpList(
											new IdExp("b"),   // a := 5; b := 3; print ( a, b, ( print( b ,
											
											new PairExpList(
													new NumExp(0),	// a := 5; b := 3; print ( a, b, ( print( b , 0
													
													new PairExpList(
															new NumExp(1), 	// a := 5; b := 3; print ( a, b, ( print( b , 0, 1
															
															new LastExpList(new NumExp(2))	// a := 5; b := 3; print ( a, b, ( print( b , 0, 1, 2 )
														)
												)
										)	 
								),
							
							new IdExp("a")	// a := 5; b := 3; print ( a, b, ( print( b , 0, 1, 2 ), a ) )
						))
					)
				))
			)				
		);
		
		//a := 8; print ((a := a + 4, a), a / 2)
		Stm prog2 = new CompoundStm(
				new AssignStm("a", new NumExp(8)),			//a := 8
				new PrintStm(new PairExpList(				//a := 8; print (
						new EseqExp(new AssignStm("a", 		//a := 8; print (a :=
									new OpExp(new IdExp("a"), //a := 8; print (a := (a
									OpExp.Plus,				//a := 8; print (a := (a +
									new NumExp(4))			//a := 8; print ((a := a + 4
								),  
								new IdExp("a")				//a := 8; print ((a := a + 4, a)
						),
						new LastExpList(
								new OpExp(new IdExp("a"),	//a := 8; print ((a := a + 4, a), a
										OpExp.Div,			//a := 8; print ((a := a + 4, a), a /
										new NumExp(2)		//a := 8; print ((a := a + 4, a), a / 2)
								)
							)
					)
				)
			);
		
		// a := 2; b := 3; b := a + b; print (a, b, a + b)
		Stm prog3 = new CompoundStm(
				new AssignStm("a", new NumExp(2)),
				new CompoundStm(
					new AssignStm("b", new NumExp(3)),
					new CompoundStm(
						new AssignStm("b", new OpExp(new IdExp("a"), OpExp.Plus, new IdExp("b"))),
						new PrintStm(new PairExpList(
								new IdExp("a"),
								new PairExpList( new IdExp("b"),
										new LastExpList(new OpExp(new IdExp("a"), OpExp.Plus, new IdExp("b"))))
							)	
						)
					)
				)
			);
				
		
		Stm currProg = prog3;
		
		System.out.println("Maxargs: " + Interpreter.maxargs(currProg));
		Interpreter.interpret(currProg);
	}
}
